#include "disp_driver.h"

#ifdef SSUD_DISP_CONTROLLER_GC9A01

void ssud_GC9A01_init(void)
{
	lcd_init_cmd_t GC_init_cmds[]={
////////////////////////////////////////////
		{0xEF, {0}, 0},
		{0xEB, {0x14}, 1},

		{0xFE, {0}, 0},
		{0xEF, {0}, 0},

		{0xEB, {0x14}, 1},
		{0x84, {0x40}, 1},
		{0x85, {0xFF}, 1},
		{0x86, {0xFF}, 1},
		{0x87, {0xFF}, 1},
		{0x88, {0x0A}, 1},
		{0x89, {0x21}, 1},
		{0x8A, {0x00}, 1},
		{0x8B, {0x80}, 1},
		{0x8C, {0x01}, 1},
		{0x8D, {0x01}, 1},
		{0x8E, {0xFF}, 1},
		{0x8F, {0xFF}, 1},
		{0xB6, {0x00, 0x20}, 2},
		//call orientation
		{0x3A, {0x05}, 1},
		{0x90, {0x08, 0x08, 0X08, 0X08}, 4},
		{0xBD, {0x06}, 1},
		{0xBC, {0x00}, 1},
		{0xFF, {0x60, 0x01, 0x04}, 3},
		{0xC3, {0x13}, 1},
		{0xC4, {0x13}, 1},
		{0xC9, {0x22}, 1},
		{0xBE, {0x11}, 1},
		{0xE1, {0x10, 0x0E}, 2},
		{0xDF, {0x21, 0x0C, 0x02}, 3},
		{0xF0, {0x45, 0x09, 0x08, 0x08, 0x26, 0x2A}, 6},
		{0xF1, {0x43, 0x70, 0x72, 0x36, 0x37, 0x6F}, 6},
		{0xF2, {0x45, 0x09, 0x08, 0x08, 0x26, 0x2A}, 6},
		{0xF3, {0x43, 0x70, 0x72, 0x36, 0x37, 0x6F}, 6},
		{0xED, {0x1B, 0x0B}, 2},
		{0xAE, {0x77}, 1},
		{0xCD, {0x63}, 1},
		{0x70, {0x07, 0x07, 0x04, 0x0E, 0x0F, 0x09, 0x07, 0X08, 0x03}, 9},
		{0xE8, {0x34}, 1},
		{0x62, {0x18, 0x0D, 0x71, 0xED, 0x70, 0x70, 0x18, 0X0F, 0x71, 0xEF, 0x70, 0x70}, 12},
		{0x63, {0x18, 0x11, 0x71, 0xF1, 0x70, 0x70, 0x18, 0X13, 0x71, 0xF3, 0x70, 0x70}, 12},
		{0x64, {0x28, 0x29, 0xF1, 0x01, 0xF1, 0x00, 0x07}, 7},
		{0x66, {0x3C, 0x00, 0xCD, 0x67, 0x45, 0x45, 0x10, 0X00, 0x00, 0x00}, 10},
		{0x67, {0x00, 0x3C, 0x00, 0x00, 0x00, 0x01, 0x54, 0X10, 0x32, 0x98}, 10},
		{0x74, {0x10, 0x85, 0x80, 0x00, 0x00, 0x4E, 0x00}, 7},
		{0x98, {0x3E, 0x07}, 2},
		{0x35, {0}, 0},
		{0x21, {0}, 0},
		{0x11, {0}, 0x80},	//0x80 delay flag
		{0x29, {0}, 0x80},	//0x80 delay flag
		{0, {0}, 0xff},		//init end flag
////////////////////////////////////////////

	};

	//Send all the commands
	rt_uint16_t cmd = 0;
	while (GC_init_cmds[cmd].databytes!=0xff) {
		ssud_spi_write_cmd(GC_init_cmds[cmd].cmd);
		ssud_spi_write_data(GC_init_cmds[cmd].data, GC_init_cmds[cmd].databytes&0x1F);
		if (GC_init_cmds[cmd].databytes & 0x80) {
			rt_thread_mdelay(100);
		}
		cmd++;
	}

	ssud_GC9A01_set_orientation(SSUD_DISP_ORIENTATION);

#ifdef SSUD_DISP_INVERT_COLORS
	ssud_spi_write_cmd(0x21);
#else
	ssud_spi_write_cmd(0x20);
#endif
}

void ssud_GC9A01_fill(rt_uint16_t x_start, rt_uint16_t y_start, rt_uint16_t x_end, rt_uint16_t y_end, void *pcolor)
{
	rt_uint8_t data[4];

	/*Column addresses*/
	ssud_spi_write_cmd(0x2A);				//0x2A
	data[0] = (x_start >> 8) & 0xFF;
	data[1] = x_start & 0xFF;
	data[2] = (x_end >> 8) & 0xFF;
	data[3] = x_end & 0xFF;
	ssud_spi_write_data(data, 4);

	/*Page addresses*/
	ssud_spi_write_cmd(0x2B);				//0x2B
	data[0] = (y_start >> 8) & 0xFF;
	data[1] = y_start & 0xFF;
	data[2] = (y_end >> 8) & 0xFF;
	data[3] = y_end & 0xFF;
	ssud_spi_write_data(data, 4);

	/*Memory write*/
	ssud_spi_write_cmd(0x2C);				//0x2C
	ssud_spi_write_color(x_start, y_start, x_end, y_end, pcolor);
}

void ssud_GC9A01_set_orientation(rt_uint8_t orientation)
{

    rt_uint8_t data[] = {0x08, 0xC8, 0x68, 0xA8}; ///ggggg
    ssud_spi_write_cmd(0x36);
    ssud_spi_write_data((void *) &data[orientation], 1);
}
#endif /* SSUD_DISP_CONTROLLER_GC9A01 */
